<template>
  <div>
    <h1>{{ count }}</h1>
    <h1>{{ state.countInReactive }}</h1>
    <h1>{{ countInRef }}</h1>
    <h1>{{ countInReactive }},{{ countInToRefs }}</h1>
    <render-function />
    <propsForSetup :title="title" />
    <contextForSetup :name="name" />
    <emitForCtxInSetup :count="countForEmit" @plus="plus" />
    <globalProperties :utils="utils" />
    <my-button>我的</my-button>
    <my-input placeholderText="我的输入框"></my-input>
    <reactivea />
    <readonlya />
    <refa />
    <computeda />
    <watchEffecta />
  </div>
</template>

<script>
// composition API 组合式API 用户层面
// hook -> 组合起来 -> Vue3.0 composition API 框架设计模式
// 将选项式API(options API)从'vue'中解构出来使用
// watch -> { watch, onMounted, computed } from 'vue'

// vue 由多个hook组合起来的框架

import { reactive, ref, toRefs } from "vue";
//setup
import renderFunction from "./components/setup/renderFunction.vue";
import propsForSetup from "./components/setup/propsForSetup.vue";
import contextForSetup from "./components/setup/contextForSetup.vue";
import emitForCtxInSetup from "./components/setup/emitForCtxInSetup.vue";
import globalProperties from "./components/setup/globalProperties.vue";
//reactivityAPIs
import reactivea from "./components/reactivityAPIs/reactive.vue";
import refa from "./components/reactivityAPIs/ref.vue";
import readonlya from "./components/reactivityAPIs/readonly.vue";
import computeda from "./components/reactivityAPIs/computed.vue";
import watchEffecta from "./components/reactivityAPIs/watchEffect.vue";

import MyButton from "./libs/MyUI/MyButton.vue";
export default {
  name: "App",
  components: {
    renderFunction,
    propsForSetup,
    contextForSetup,
    emitForCtxInSetup,
    globalProperties,
    MyButton,
    reactivea,
    refa,
    readonlya,
    computeda,
    watchEffecta,
  },
  // setup 是新的组件选项，是程序的入口，用于使用composition API
  // setup 调用时机 自动执行 初始化属性之后,组件实例被创建后 被调用 在生命周期的角度：在beforeCreate之前
  // setup return 了一个对象 对象中的属性会被融合到执行机上下文中 为了组件的template使用
  setup(props, ctx) {
    const utils = {
      a: 1,
      b: 2,
    };

    const countForEmit = ref(0);
    const plus = (num) => {
      countForEmit.value += num;
    };

    console.log(ctx);
    // const { attrs, emit, slots} = ctx;
    const name = ref("name By ctx");
    setTimeout(() => {
      name.value = "name By ctx123";
    }, 1000);
    /**
     * attrs: Proxy内部组件实例代理后的相对性的值，总是暴露最新的值，可以解构，以防止获取到不新鲜的引用
     * emit: (event, ...args) => instance.emit(event, ...args)
     * expose: exposed => {…}
     * slots: Proxy内部组件实例代理后的相对性的值，总是暴露最新的值，可以解构，以防止获取到不新鲜的引用
     */

    // console.log('setup');
    const state = reactive({
      countInReactive: 1,
      countInToRefs: 3,
    });

    const countInRef = ref(2);

    // ref 生成的值是响应式的，是一个对象 要通过 .value 去取或者设置其值
    // 在template 访问时不需要再用.value取值
    console.log(countInRef.value);

    setTimeout(() => {
      countInRef.value = 5;
    }, 2000);

    const title = ref("我是Vue");
    setTimeout(() => {
      title.value = "我是Vue3.0";
    }, 2000);

    return {
      state,
      count: 0,
      countInRef,
      ...toRefs(state),
      title,
      name,
      countForEmit,
      plus,
      utils,
      //...state 会损失state 的响应式性能，要使用toRefs转换包起来
    };
  },
};
</script>

<style></style>
